package dao.impl;

import dao.ClientDAO;
import dao.DAOFactory;
import dao.GroupDAO;
import dao.RelationDAO;

import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ConcurrentSkipListSet;

public class MemDAOFactory implements DAOFactory
{
    private ClientDAO   clientDAO;
    private GroupDAO    groupDAO;
    private RelationDAO relationDAO;

    public MemDAOFactory()
    {
        clientDAO = new MemClientDAO();
        groupDAO = new MemGroupDAO();
        relationDAO = new MemRelationDAO();
    }

    @Override
    public ClientDAO getClientDAO()
    {
        return clientDAO;
    }

    @Override
    public GroupDAO getGroupDAO()
    {
        return groupDAO;
    }

    @Override
    public RelationDAO getRelationDAO()
    {
        return relationDAO;
    }

    class MemRelationDAO implements RelationDAO
    {
        private ConcurrentMap<String, Set<String>> clientJoinGroups = new ConcurrentHashMap<>();
        private ConcurrentMap<String, Set<String>> groupHasClients  = new ConcurrentHashMap<>();

        @Override
        public void save(String groupId, String clientId)
        {
            Set<String> groupIds = clientJoinGroups.get(clientId);
            if (groupIds == null)
            {
                groupIds = new ConcurrentSkipListSet<>();
                clientJoinGroups.put(clientId, groupIds);
            }
            if (groupIds.contains(groupId))
            {
                throw new IllegalStateException("该群聊已经包含该客户端，不需要重复加入");
            }
            groupIds.add(clientId);
            Set<String> clientIds = groupHasClients.get(groupId);
            if (clientIds == null)
            {
                clientIds = new ConcurrentSkipListSet<>();
                groupHasClients.put(groupId, clientIds);
            }
            if (clientIds.contains(clientId))
            {
                throw new IllegalStateException("该群聊已经包含该客户端，不需要重复加入");
            }
            clientIds.add(clientId);
        }

        @Override
        public boolean findGroups(String clientId, String groupId)
        {
            Set<String> groupdIds = clientJoinGroups.get(clientId);
            if (groupdIds == null || groupdIds.contains(groupId) == false)
            {
                return false;
            }
            return true;
        }

        @Override
        public Collection<String> findClients(String groupId)
        {
            return groupHasClients.get(groupId);
        }

        @Override
        public Collection<String> findGroups(String clientId)
        {
            return clientJoinGroups.get(clientId);
        }
    }

    class MemClientDAO implements ClientDAO
    {
        private ConcurrentMap<String, String> store = new ConcurrentHashMap<>();

        @Override
        public String find(String clientName)
        {
            return store.get(clientName);
        }

        @Override
        public String saveClient(String clientName)
        {
            String clientId = UUID.randomUUID().toString();
            String pre      = store.putIfAbsent(clientName, clientId);
            if (pre != null)
            {
                throw new IllegalStateException("不允许重复的客户端标识");
            }
            return clientId;
        }
    }

    class MemGroupDAO implements GroupDAO
    {
        private ConcurrentMap<String, String> store = new ConcurrentHashMap<>();
        private ConcurrentMap<String, String> query = new ConcurrentHashMap<>();

        @Override
        public String find(String clientName)
        {
            return store.get(clientName);
        }

        @Override
        public String getGroupNameById(String groupId)
        {
            return query.get(groupId);
        }

        @Override
        public String saveGroup(String groupName)
        {
            String groupId = UUID.randomUUID().toString();
            Object pre     = store.putIfAbsent(groupName, groupId);
            if (pre != null)
            {
                throw new IllegalStateException("不允许重复的客户端标识");
            }
            query.put(groupId, groupName);
            return groupId;
        }
    }
}
